home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / bench / dinomometer.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  21KB  |  672 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * dinomometer - a synthetic modeling benchmark for OpenGL by Mark Kilgard
  19.  * Silicon Graphics November 15, 1993 $Revision: 1.1 $
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <sys/time.h>
  26. #include <math.h>        /* for cos(), sin(), and sqrt() */
  27. #include <GL/gl.h>
  28. #include <GL/glx.h>        /* this includes the necessary X and gl.h
  29.                  * headers */
  30. #include <GL/glu.h>        /* gluPerspective(), gluLookAt(), GLU polygon
  31.                  * tesselator */
  32. #include <X11/Xatom.h>        /* for XA_RGB_DEFAULT_MAP atom */
  33. #include <X11/Xmu/StdCmap.h>    /* for XmuLookupStandardColormap() */
  34.  
  35. typedef enum {
  36.     RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, ARM_SIDE, ARM_EDGE, ARM_WHOLE,
  37.     LEG_SIDE, LEG_EDGE, LEG_WHOLE, EYE_SIDE, EYE_EDGE, EYE_WHOLE, DINOSAUR
  38. }               displayLists;
  39.  
  40. void
  41. hello(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
  42. {
  43.    printf("%g, %g, %g, %g\n", angle, x, y, z);
  44. }
  45.  
  46. Display        *dpy;
  47. Window          win;
  48. Pixmap          pixmap;
  49. GLXPixmap       glxpixmap;
  50. GC              gc;
  51. GLfloat         angle = -150;    /* in degrees */
  52. GLboolean       doubleBuffer = GL_TRUE, clear = GL_TRUE, verbose = GL_FALSE, immediate = GL_FALSE;
  53. GLboolean       direct = GL_TRUE, outline = GL_FALSE, backcull = GL_TRUE, lighting = GL_TRUE;
  54. GLboolean       usePixmap = GL_FALSE, finePrint = GL_TRUE;
  55. int             X = 10, Y = 10, W = 300, H = 300, duration = 10, totalPolys = 0;
  56. int             reps = 1;
  57. XSizeHints      sizeHints =
  58. {0};
  59. GLdouble        bodyWidth = 2.0;
  60. GLenum          primativeType;
  61. int             vertices, numPolys;
  62. char            revision[15], version[15];
  63. int             configuration[] =
  64. {GLX_DOUBLEBUFFER, GLX_RGBA, GLX_DEPTH_SIZE, 16, None};
  65. GLfloat         body[][2] =
  66. {
  67.     {0, 3},
  68.     {1, 1},
  69.     {5, 1},
  70.     {8, 4},
  71.     {10, 4},
  72.     {11, 5},
  73.     {11, 11.5},
  74.     {13, 12},
  75.     {13, 13},
  76.     {10, 13.5},
  77.     {13, 14},
  78.     {13, 15},
  79.     {11, 16},
  80.     {8, 16},
  81.     {7, 15},
  82.     {7, 13},
  83.     {8, 12},
  84.     {7, 11},
  85.     {6, 6},
  86.     {4, 3},
  87.     {3, 2},
  88.     {1, 2}};
  89. GLfloat         arm[][2] =
  90. {
  91.     {8, 10},
  92.     {9, 9},
  93.     {10, 9},
  94.     {13, 8},
  95.     {14, 9},
  96.     {16, 9},
  97.     {15, 9.5},
  98.     {16, 10},
  99.     {15, 10},
  100.     {15.5, 11},
  101.     {14.5, 10},
  102.     {14, 11},
  103.     {14, 10},
  104.     {13, 9},
  105.     {11, 11},
  106.     {9, 11}};
  107. GLfloat         leg[][2] =
  108. {
  109.     {8, 6},
  110.     {8, 4},
  111.     {9, 3},
  112.     {9, 2},
  113.     {8, 1},
  114.     {8, 0.5},
  115.     {9, 0},
  116.     {12, 0},
  117.     {10, 1},
  118.     {10, 2},
  119.     {12, 4},
  120.     {11, 6},
  121.     {10, 7},
  122.     {9, 7}};
  123. GLfloat         eye[][2] =
  124. {
  125.     {8.75, 15},
  126.     {9, 14.7},
  127.     {9.6, 14.7},
  128.     {10.1, 15},
  129.     {9.6, 15.25},
  130.     {9, 15.25}};
  131. GLfloat         lightZeroPosition[] =
  132. {10.0, 4.0, 10.0, 1.0};
  133. GLfloat         lightZeroColor[] =
  134. {0.8, 1.0, 0.8, 1.0};        /* green-tinted */
  135. GLfloat         lightOnePosition[] =
  136. {-1.0, -2.0, 1.0, 0.0};
  137. GLfloat         lightOneColor[] =
  138. {0.6, 0.3, 0.2, 1.0};        /* red-tinted */
  139. GLfloat         skinColor[] =
  140. {0.1, 1.0, 0.1, 1.0}, eyeColor[] =
  141. {1.0, 0.2, 0.2, 1.0};
  142. char           *drawable;
  143.  
  144. #include "immediate.c"
  145. #define DoLighting
  146. #include "immediate.c"
  147. #undef DoLighting
  148.  
  149. void
  150. fatalError(char *message)
  151. {
  152.     fprintf(stderr, "glxdino: %s\n", message);
  153.     exit(1);
  154. }
  155.  
  156. Colormap
  157. getColormap(XVisualInfo * vi)
  158. {
  159.     Status          status;
  160.     XStandardColormap *standardCmaps;
  161.     Colormap        cmap;
  162.     int             i, numCmaps;
  163.  
  164.     /* be lazy; using DirectColor too involved for this example */
  165.     if (vi->class != TrueColor)
  166.     fatalError("no support for non-TrueColor visual");
  167.     /* if no standard colormap but TrueColor, just make an unshared one */
  168.     status = XmuLookupStandardColormap(dpy, vi->screen, vi->visualid,
  169.      vi->depth, XA_RGB_DEFAULT_MAP, /* replace */ False, /* retain */ True);
  170.     if (status == 1) {
  171.     status = XGetRGBColormaps(dpy, RootWindow(dpy, vi->screen),
  172.                  &standardCmaps, &numCmaps, XA_RGB_DEFAULT_MAP);
  173.     if (status == 1)
  174.         for (i = 0; i < numCmaps; i++)
  175.         if (standardCmaps[i].visualid == vi->visualid) {
  176.             cmap = standardCmaps[i].colormap;
  177.             XFree(standardCmaps);
  178.             return cmap;
  179.         }
  180.     }
  181.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
  182.     return cmap;
  183. }
  184.  
  185. /* #define GenerateImmediateModeCode /* */
  186.  
  187. #ifdef GenerateImmediateModeCode
  188. #define CodeGen(msg) printf("%s\n", msg);
  189. #define CodeGen3(msg,x,y,z) printf(msg,x,y,z);
  190. #else
  191. #define CodeGen(msg)
  192. #define CodeGen3(msg,x,y,z)
  193. #endif
  194.  
  195. static void
  196. myBegin(GLenum type)
  197. {
  198.     primativeType = type;
  199.     vertices = 0;
  200.     glBegin(type);
  201. #ifdef GenerateImmediateModeCode
  202.     switch (type) {
  203.     case GL_TRIANGLE_FAN:
  204.     printf("glBegin(GL_TRIANGLE_FAN);\n");
  205.     break;
  206.     case GL_TRIANGLE_STRIP:
  207.     printf("glBegin(GL_TRIANGLE_STRIP);\n");
  208.     break;
  209.     case GL_TRIANGLES:
  210.     printf("glBegin(GL_TRIANGLES);\n");
  211.     break;
  212.     default:
  213.     printf("ERROR\n");
  214.     }
  215. #endif
  216. }
  217.  
  218. static void
  219. myVertex(GLfloat * vertex)
  220. {
  221.     vertices++;
  222.     glVertex2fv(vertex);    /* semi-tricky */
  223. #ifdef GenerateImmediateModeCode
  224.     printf("glVertex2f(%g,%g);\n", vertex[0], vertex[1]);
  225. #endif
  226. }
  227.  
  228. static void
  229. myEnd()
  230. {
  231.     switch (primativeType) {
  232.     case GL_TRIANGLE_FAN:
  233.     case GL_TRIANGLE_STRIP:
  234.     numPolys += vertices - 2;
  235.     break;
  236.     case GL_TRIANGLES:
  237.     numPolys += vertices / 3;
  238.     break;
  239.     }
  240.     glEnd();
  241. #ifdef GenerateImmediateModeCode
  242.     printf("glEnd();\n");
  243. #endif
  244. }
  245.  
  246. int
  247. extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize, GLdouble thickness, GLuint side,
  248.             GLuint edge, GLuint whole)
  249. {
  250.     static GLUtriangulatorObj *tobj = NULL;
  251.     GLdouble        vertex[3], dx, dy, len;
  252.     int             i;
  253.     int             count = dataSize / (2 * sizeof(GLfloat));
  254.  
  255.     if (tobj == NULL) {
  256.     tobj = gluNewTess();    /* create and initialize a GLU polygon
  257.                  * tesselation object */
  258.     gluTessCallback(tobj, GLU_BEGIN, myBegin);
  259.     gluTessCallback(tobj, GLU_VERTEX, myVertex);
  260.     gluTessCallback(tobj, GLU_END, myEnd);
  261.     }
  262.     CodeGen("/* side */");
  263.     glNewList(side, GL_COMPILE);
  264.     CodeGen("glShadeModel(GL_SMOOTH);");
  265.     glShadeModel(GL_SMOOTH);    /* smooth shade minimizes seeing tessellation */
  266.     numPolys = 0;
  267.     gluBeginPolygon(tobj);
  268.     for (i = 0; i < count; i++) {
  269.     vertex[0] = data[i][0];
  270.     vertex[1] = data[i][1];
  271.     vertex[2] = 0;
  272.     gluTessVertex(tobj, vertex, &data[i]);
  273.     }
  274.     gluEndPolygon(tobj);
  275.     glEndList();
  276.     CodeGen("/* edge */");
  277.     glNewList(edge, GL_COMPILE);
  278.     CodeGen("glShadeModel(GL_FLAT);");
  279.     glShadeModel(GL_FLAT);    /* flat shade keeps angular hands from being
  280.                  * "smoothed" */
  281.     CodeGen("glBegin(GL_QUAD_STRIP);");
  282.     glBegin(GL_QUAD_STRIP);
  283.     for (i = 0; i <= count; i++) {    /* mod function handles closing the
  284.                      * edge */
  285.     glVertex3f(data[i % count][0], data[i % count][1], 0.0);
  286.     CodeGen3("glVertex3f(%g,%g,%g);\n", data[i % count][0], data[i % count][1], 0.0);
  287.     /*
  288.      * Calculate a unit normal by dividing by Euclidean distance. We
  289.      * could be lazy and use glEnable(GL_NORMALIZE) so we could pass in
  290.      * arbitrary normals for a very slight performance hit.
  291.      */
  292.     dx = data[(i + 1) % count][1] - data[i % count][1];
  293.     dy = data[i % count][0] - data[(i + 1) % count][0];
  294.     len = sqrt(dx * dx + dy * dy);
  295.     if (lighting) {
  296.         glNormal3f(dx / len, dy / len, 0.0);    /* last normal is
  297.                              * extraneous */
  298.         CodeGen3("glNormal3f(%g,%g,%g);\n", dx / len, dy / len, 0.0);
  299.     }
  300.     glVertex3f(data[i % count][0], data[i % count][1], thickness);
  301.     CodeGen3("glVertex3f(%g,%g,%g);\n", data[i % count][0], data[i % count][1], thickness);
  302.     }
  303.     CodeGen("glEnd();");
  304.     glEnd();
  305.     glEndList();
  306.     CodeGen("/* whole solid */");
  307.     glNewList(whole, GL_COMPILE);
  308.     CodeGen("glFrontFace(GL_CW);");
  309.     if (backcull)
  310.     glFrontFace(GL_CW);
  311.     CodeGen("/* call edge routine */");
  312.     glCallList(edge);
  313.     CodeGen("glNormal3f(0.0, 0.0, -1.0);");
  314.     if (lighting)
  315.     glNormal3f(0.0, 0.0, -1.0);    /* constant normal for side */
  316.     CodeGen("/* call side routine */");
  317.     glCallList(side);
  318.     CodeGen("glPushMatrix();");
  319.     glPushMatrix();
  320.     CodeGen3("glTranslatef(%g,%g,%g);\n", 0.0, 0.0, thickness);
  321.     glTranslatef(0.0, 0.0, thickness);
  322.     CodeGen("glFrontFace(GL_CCW);");
  323.     if (backcull)
  324.     glFrontFace(GL_CCW);
  325.     CodeGen("glNormal3f(0.0, 0.0, 1.0);");
  326.     if (lighting)
  327.     glNormal3f(0.0, 0.0, 1.0);    /* opposite constant normal for other
  328.                      * side */
  329.     CodeGen("/* call side routine */");
  330.     glCallList(side);
  331.     CodeGen("glPopMatrix();");
  332.     glPopMatrix();
  333.     glEndList();
  334.     return numPolys * 2 + count + 1;
  335. }
  336.  
  337. int
  338. makeDinosaur(void)
  339. {
  340.     GLfloat         bodyWidth = 3.0;
  341.     int             bodyPolys, armPolys, legPolys, eyePolys;
  342.  
  343.     CodeGen("/* the body */");
  344.     bodyPolys = extrudeSolidFromPolygon(body, sizeof(body), bodyWidth,
  345.                     BODY_SIDE, BODY_EDGE, BODY_WHOLE);
  346.     CodeGen("/* an arm */");
  347.     armPolys = extrudeSolidFromPolygon(arm, sizeof(arm), bodyWidth / 4,
  348.                        ARM_SIDE, ARM_EDGE, ARM_WHOLE);
  349.     CodeGen("/* a leg */");
  350.     legPolys = extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 2,
  351.                        LEG_SIDE, LEG_EDGE, LEG_WHOLE);
  352.     CodeGen("/* the eyes */");
  353.     eyePolys = extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2,
  354.                        EYE_SIDE, EYE_EDGE, EYE_WHOLE);
  355.     glNewList(DINOSAUR, GL_COMPILE);
  356.     CodeGen("glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);");
  357.     glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);
  358.     glCallList(BODY_WHOLE);
  359.     CodeGen("glPushMatrix();");
  360.     glPushMatrix();
  361.     CodeGen3("glTranslatef(%g,%g,%g);\n", 0.0, 0.0, bodyWidth);
  362.     glTranslatef(0.0, 0.0, bodyWidth);
  363.     CodeGen("/* call arm routine */");
  364.     glCallList(ARM_WHOLE);
  365.     CodeGen("/* call leg routine */");
  366.     glCallList(LEG_WHOLE);
  367.     CodeGen3("glTranslatef(%g,%g,%g);\n", 0.0, 0.0, -bodyWidth - bodyWidth / 4);
  368.     glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4);
  369.     CodeGen("/* call arm routine */");
  370.     glCallList(ARM_WHOLE);
  371.     CodeGen3("glTranslatef(%g,%g,%g);\n", 0.0, 0.0, -bodyWidth / 4);
  372.     glTranslatef(0.0, 0.0, -bodyWidth / 4);
  373.     CodeGen("/* call leg routine */");
  374.     glCallList(LEG_WHOLE);
  375.     CodeGen3("glTranslatef(%g,%g,%g);\n", 0.0, 0.0, bodyWidth / 2 - 0.1);
  376.     glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1);
  377.     CodeGen("glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);");
  378.     glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);
  379.     CodeGen("/* call eye routine */");
  380.     glCallList(EYE_WHOLE);
  381.     CodeGen("glPopMatrix();");
  382.     glPopMatrix();
  383.     glEndList();
  384.     return bodyPolys + armPolys * 2 + legPolys * 2 + eyePolys * 2;
  385. }
  386.  
  387. void
  388. main(int argc, char **argv)
  389. {
  390.     XVisualInfo    *vi;
  391.     Colormap        cmap;
  392.     XSetWindowAttributes swa;
  393.     GLXContext      cx;
  394.     char           *display = NULL, *geometry = NULL;
  395.     int             flags, i, n, depthBufferDepth, dinoRenders, warmup;
  396.     float           elapsed;
  397.     struct timeval  beginTime, finishTime;
  398.  
  399.     /*** (1) process normal X command line arguments ***/
  400.     for (i = 1; i < argc; i++) {
  401.     if (!strcmp(argv[i], "-geometry")) {
  402.         i++;
  403.         if (i >= argc)
  404.         fatalError("follow -geometry option with geometry parameter");
  405.         geometry = argv[i];
  406.     } else if (!strcmp(argv[i], "-display")) {
  407.         i++;
  408.         if (i >= argc)
  409.         fatalError("follow -display option with display parameter");
  410.         display = argv[i];
  411.     } else if (!strcmp(argv[i], "-time")) {
  412.         i++;
  413.         if (i >= argc)
  414.         fatalError("follow -time option with seconds to run");
  415.         duration = atoi(argv[i]);
  416.     } else if (!strcmp(argv[i], "-repeat")) {
  417.         i++;
  418.         if (i >= argc)
  419.         fatalError("follow -repeat option with repeat count");
  420.         reps = atoi(argv[i]);
  421.     } else if (!strcmp(argv[i], "-single"))
  422.         doubleBuffer = GL_FALSE;
  423.     else if (!strcmp(argv[i], "-noclear"))
  424.         clear = GL_FALSE;
  425.     else if (!strcmp(argv[i], "-indirect"))
  426.         direct = GL_FALSE;
  427.     else if (!strcmp(argv[i], "-outline"))
  428.         outline = GL_TRUE;
  429.     else if (!strcmp(argv[i], "-nocull"))
  430.         backcull = GL_FALSE;
  431.     else if (!strcmp(argv[i], "-nolight"))
  432.         lighting = GL_FALSE;
  433.     else if (!strcmp(argv[i], "-immediate"))
  434.         immediate = GL_TRUE;
  435.     else if (!strcmp(argv[i], "-pixmap"))
  436.         usePixmap = GL_TRUE;
  437.     else if (!strcmp(argv[i], "-nofineprint"))
  438.         finePrint = GL_FALSE;
  439.     else if (!strcmp(argv[i], "-verbose"))
  440.         verbose = GL_TRUE;
  441.     else {
  442.         printf("\ndinomometer options:\n");
  443.         printf("   -display str   X display, str is display name\n");
  444.         printf("   -geometry #x#  window size, WxH+X+Y\n");
  445.         printf("   -time #        time to run test, followed by # in seconds\n");
  446.         printf("   -repeat #      number of iternations to run\n");
  447.         printf("   -single        single buffered (default: double buffered if available)\n");
  448.         printf("   -noclear       skip depth and image buffer clear per dino\n");
  449.         printf("   -indirect      indirect rendering (default: direct if available)\n");
  450.         printf("   -outline       outlines of polygons (default: filled)\n");
  451.         printf("   -nocull        disable back face culling (default: enabled\n");
  452.         printf("   -nolight       disable lighting and normals (default: enabled\n");
  453.         printf("   -nofineprint   don't print all the fine print info\n");
  454.         printf("   -pixmap        render into pixmaps (forces indirect)\n");
  455.         printf("   -verbose       print warmup estimate info\n\n");
  456.         exit(1);
  457.     }
  458.     }
  459.  
  460.     /*** (2) open a connection to the X server ***/
  461.     dpy = XOpenDisplay(display);
  462.     if (dpy == NULL)
  463.     fatalError("could not open display");
  464.  
  465.     /*** (3) make sure OpenGL's GLX extension supported ***/
  466.     if (!glXQueryExtension(dpy, NULL, NULL))
  467.     fatalError("X server has no OpenGL GLX extension");
  468.  
  469.     /*** (4) find an appropriate visual and a colormap for it ***/
  470.     /* find an OpenGL-capable RGB visual with depth buffer */
  471.     if (!doubleBuffer)
  472.     goto SingleBufferOverride;
  473.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), configuration);
  474.     if (vi == NULL) {
  475.       SingleBufferOverride:
  476.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), &configuration[1]);
  477.     if (vi == NULL)
  478.         fatalError("no appropriate RGB visual with depth buffer");
  479.     doubleBuffer = GL_FALSE;
  480.     }
  481.     cmap = getColormap(vi);
  482.  
  483.     /*** (5) create an OpenGL rendering context  ***/
  484.     /* create an OpenGL rendering context */
  485.     if (usePixmap)
  486.     direct = GL_FALSE;
  487.     cx = glXCreateContext(dpy, vi, /* no sharing of display lists */ NULL,
  488.                /* direct rendering if possible */ direct);
  489.     if (cx == NULL)
  490.     fatalError("could not create rendering context");
  491.  
  492.     /*** (6) create an X window with the selected visual and right properties ***/
  493.     flags = XParseGeometry(geometry, &X, &Y, (unsigned int *) &W, (unsigned int *) &H);
  494.     if (XValue & flags) {
  495.     if (XNegative & flags)
  496.         X = DisplayWidth(dpy, DefaultScreen(dpy)) + X - sizeHints.width;
  497.     }
  498.     if (YValue & flags) {
  499.     if (YNegative & flags)
  500.         Y = DisplayHeight(dpy, DefaultScreen(dpy)) + Y - sizeHints.height;
  501.     }
  502.     swa.colormap = cmap;
  503.     swa.border_pixel = 0;
  504.     swa.override_redirect = True;
  505.     win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), X, Y, W, H,
  506.             0, vi->depth, InputOutput, vi->visual,
  507.              CWBorderPixel | CWColormap | CWOverrideRedirect, &swa);
  508.     if (usePixmap) {
  509.     XGCValues       gcval;
  510.  
  511.     pixmap = XCreatePixmap(dpy, win, W, H, vi->depth);
  512.     glxpixmap = glXCreateGLXPixmap(dpy, vi, pixmap);
  513.     gcval.graphics_exposures = 0;
  514.     gc = XCreateGC(dpy, pixmap, GCGraphicsExposures, &gcval);
  515.     }
  516.     /*** (7) bind the rendering context to the window ***/
  517.     if (!usePixmap) {
  518.     glXMakeCurrent(dpy, win, cx);
  519.     } else {
  520.     glXMakeCurrent(dpy, glxpixmap, cx);
  521.     }
  522.  
  523.     /*** (8) make the desired display lists ***/
  524.     totalPolys = makeDinosaur();
  525.  
  526.     /*** (9) configure the OpenGL context for rendering ***/
  527.     glViewport(0, 0, W, H);    /* XXX workaround Reality Engine bug */
  528.     if (backcull)
  529.     glEnable(GL_CULL_FACE);    /* ~50% better perfomance than no back-face
  530.                  * culling on Entry Indigo */
  531.     glEnable(GL_DEPTH_TEST);    /* enable depth buffering */
  532.     if (lighting)
  533.     glEnable(GL_LIGHTING);    /* enable lighting */
  534.     glMatrixMode(GL_PROJECTION);/* set up projection transform */
  535.     gluPerspective( /* field of view in degree */ 40.0, /* aspect ratio */ 1.0,
  536.             /* Z near */ 1.0, /* Z far */ 40.0);
  537.     glMatrixMode(GL_MODELVIEW);    /* now change to modelview */
  538.     gluLookAt(0.0, 0.0, 30.0,    /* eye is at (0,0,30) */
  539.           0.0, 0.0, 0.0,    /* center is at (0,0,0) */
  540.           0.0, 1.0, 0.);    /* up is in postivie Y direction */
  541.     glPushMatrix();        /* dummy push so we can pop on model recalc */
  542.     glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
  543.     glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition);
  544.     glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
  545.     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
  546.     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
  547.     glLightfv(GL_LIGHT1, GL_POSITION, lightOnePosition);
  548.     glLightfv(GL_LIGHT1, GL_DIFFUSE, lightOneColor);
  549.     glEnable(GL_LIGHT0);
  550.     glEnable(GL_LIGHT1);    /* enable both lights */
  551.     if (outline)
  552.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  553.     glDrawBuffer(GL_FRONT);
  554.  
  555.     /*** (10) request the X window to be displayed on the screen ***/
  556.     XMapWindow(dpy, win);
  557.     XInstallColormap(dpy, cmap);
  558.     glXWaitX();
  559.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  560.  
  561. #define RENDER(how) \
  562.     glPopMatrix(); \
  563.     glPushMatrix(); \
  564.     glRotatef(angle, 0.0, 1.0, 0.0); \
  565.     glTranslatef(-8, -8, -bodyWidth / 2); \
  566.     if(clear) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); \
  567.     how; \
  568.     angle -= 60.12345;        /* full rotation every 6 frames gives more
  569.                  * fair workload */
  570.  
  571.     if (usePixmap) {
  572.     warmup = 15 + duration / 3;
  573.     } else {
  574.     warmup = glXIsDirect(dpy, cx) ? 30 : 30 + duration * 3;
  575.     }
  576.     if (verbose) {
  577.     printf("\nDoing %d warm ups...", warmup);
  578.     fflush(stdout);
  579.     }
  580.     gettimeofday(&beginTime);
  581.     if (immediate) {
  582.     if (lighting) {
  583.         for (i = 0; i < warmup; i++) {
  584.         RENDER(renderDinosaur())
  585.         }
  586.     } else {
  587.         for (i = 0; i < warmup; i++) {
  588.         RENDER(renderDinosaurNoLite())
  589.         }
  590.     }
  591.     } else {
  592.     for (i = 0; i < warmup; i++) {
  593.         RENDER(glCallList(DINOSAUR));
  594.     }
  595.     }
  596.     glFinish();
  597.     gettimeofday(&finishTime);
  598.     if (finishTime.tv_usec < beginTime.tv_usec) {
  599.     finishTime.tv_usec += 1000000;
  600.     finishTime.tv_sec -= 1;
  601.     }
  602.     elapsed = (float) (finishTime.tv_usec - beginTime.tv_usec) / 1000000.0 +
  603.     (float) (finishTime.tv_sec - beginTime.tv_sec);
  604.     if (verbose)
  605.     printf(" estimated rate = %g dinos/second\n", (float) warmup / elapsed);
  606.     if (usePixmap) {
  607.     if (verbose)
  608.         printf("\nShowing pixmap.\n");
  609.     XCopyArea(dpy, pixmap, win, gc, 0, 0, W, H, 0, 0);
  610.     XSync(dpy, 0);
  611.     }
  612.     dinoRenders = (float) warmup / elapsed * duration;
  613.     if (dinoRenders < 18)
  614.     dinoRenders = 18;    /* always do at least 18 */
  615.  
  616.     /*** (11) begin iterations ***/
  617.     sscanf("$Revision: 1.1 $", "%s %s $", revision, version);
  618.     printf("\nOpenGL Dinomometer (version %s)\n\n", version);
  619.     for (n = 0; n < reps; n++) {
  620.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  621.     gettimeofday(&beginTime);
  622.     if (immediate) {
  623.         if (lighting) {
  624.         for (i = 0; i < dinoRenders; i++) {
  625.             RENDER(renderDinosaur())
  626.         }
  627.         } else {
  628.         for (i = 0; i < dinoRenders; i++) {
  629.             RENDER(renderDinosaurNoLite())
  630.         }
  631.         }
  632.     } else {
  633.         for (i = 0; i < dinoRenders; i++) {
  634.         RENDER(glCallList(DINOSAUR))
  635.         }
  636.     }
  637.     glFinish();
  638.     gettimeofday(&finishTime);
  639.     if (finishTime.tv_usec < beginTime.tv_usec) {
  640.         finishTime.tv_usec += 1000000;
  641.         finishTime.tv_sec -= 1;
  642.     }
  643.     elapsed = (float) (finishTime.tv_usec - beginTime.tv_usec) / 1000000.0 +
  644.         (float) (finishTime.tv_sec - beginTime.tv_sec);
  645.  
  646.     printf("FlyntStones:  %g dinos/second\n", (float) dinoRenders / elapsed);
  647.     printf("              %g polys/second\n\n", (float) totalPolys * dinoRenders / elapsed);
  648.     }
  649.     drawable = usePixmap ? "pixmap" : "window";
  650.     if (finePrint) {
  651.     printf("THE FINE PRINT: %s depth %d bits/pixel, %d polys/dino,\n",
  652.            drawable, vi->depth, totalPolys);
  653.     printf("back-face culling %s, polygon mode is %s, lighting %s,\n",
  654.            backcull ? "on" : "off",
  655.            outline ? "line" : "filled",
  656.            lighting ? "on" : "off");
  657.     printf("%d dinos rendered, rendering is %s, vendor is\n",
  658.            dinoRenders, glXIsDirect(dpy, cx) ? "direct" : "indirect");
  659.     glGetIntegerv(GL_DEPTH_BITS, &depthBufferDepth);
  660.     printf("%s, renderer is %s, version is %s, %d bits of depth\n",
  661.            glGetString(GL_VENDOR), glGetString(GL_RENDERER),
  662.            glGetString(GL_VERSION), depthBufferDepth);
  663.     printf("buffer, %d pixel %s width, %d pixel %s height,\n",
  664.            W, drawable, H, drawable);
  665.     printf("using %s, spent %g actual seconds\n",
  666.            immediate ? "immediate mode" : "display lists",
  667.            elapsed);
  668.     printf("benchmarking.\n\n");
  669.     }
  670.     exit(0);
  671. }
  672.